package org.origin.ferret.system.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.origin.centre.model.base.XPage;
import org.origin.centre.model.dto.XDeleteByIdDto;
import org.origin.centre.model.dto.XQueryByIdDto;
import org.origin.centre.model.dto.XUpdateByIdDto;
import org.origin.centre.model.dto.dict.XQueryByTreeValueDto;
import org.origin.centre.model.enums.XUsable;
import org.origin.centre.model.vo.XPageVo;
import org.origin.centre.model.vo.dict.XTreeKeyValueVo;
import org.origin.centre.utils.UserUtil;
import org.origin.ferret.system.mapper.SysRoleMapper;
import org.origin.ferret.system.mapstruct.SysRoleMapstruct;
import org.origin.ferret.system.model.dto.role.SysRoleInsertDto;
import org.origin.ferret.system.model.dto.role.SysRolePageDto;
import org.origin.ferret.system.model.dto.role.SysRoleUpdateDto;
import org.origin.ferret.system.model.entity.SysRoleEntity;
import org.origin.ferret.system.model.vo.role.SysRoleVo;
import org.origin.ferret.system.service.SysRoleService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static org.origin.ferret.system.model.entity.table.SysRoleEntityTableDef.SYS_ROLE_ENTITY;

/**
 * 系统角色-服务
 *
 * @author ferret
 * @version 2024-05-08
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl implements SysRoleService {
    private final SysRoleMapper roleMapper;
    private final SysRoleMapstruct roleMapstruct;

    @Override
    public XPageVo<SysRoleVo> page(XPage<SysRolePageDto> pageDto) {
        SysRolePageDto params = pageDto.getParams();
        Page<SysRoleEntity> pagePojo = this.roleMapper
                .paginate(pageDto.getPageNum(), pageDto.getPageSize(), QueryWrapper.create()
                        .where(SYS_ROLE_ENTITY.PARENT_ID.eq(params.getParentId(), !UserUtil.isAdmin()))
                        .and(SYS_ROLE_ENTITY.NAME.like(params.getName(), StringUtils::isNotBlank))
                        .and(SYS_ROLE_ENTITY.STATUS.eq(params.getStatus(), Objects::nonNull))
                        .orderBy(SYS_ROLE_ENTITY.STATUS.asc())
                        .orderBy(SYS_ROLE_ENTITY.CREATE_TIME.desc())
                        .orderBy(SYS_ROLE_ENTITY.ID.desc())
                );
        return new XPageVo<SysRoleVo>()
                .of(pageDto, pagePojo.getTotalRow(),
                        pagePojo.getRecords(), this.roleMapstruct::toVo);
    }

    @Override
    public SysRoleVo query(XQueryByIdDto queryDto) {
        SysRoleEntity entity = this.roleMapper.selectOneById(queryDto.getId());
        return this.roleMapstruct.toVo(entity);
    }

    @Override
    public Boolean insert(SysRoleInsertDto insertDto) {
        SysRoleEntity entity = this.roleMapstruct.toEntity(insertDto);
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preInsert();
        int insertNum = this.roleMapper.insert(entity);
        return insertNum > 0;
    }

    @Override
    public Boolean update(SysRoleUpdateDto updateDto) {
        SysRoleEntity entity = this.roleMapstruct.toEntity(updateDto);
        entity.setStatus(null);
        entity.preUpdate();
        int updateNum = this.roleMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean delete(XDeleteByIdDto deleteDto) {
        int updateNum = this.roleMapper.deleteById(deleteDto.longId());
        return updateNum > 0;
    }

    @Override
    public Boolean valid(XUpdateByIdDto updateDto) {
        SysRoleEntity entity = new SysRoleEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preUpdate();
        int updateNum = this.roleMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean invalid(XUpdateByIdDto updateDto) {
        SysRoleEntity entity = new SysRoleEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.DISABLE.getCode());
        entity.preUpdate();
        int updateNum = this.roleMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public List<XTreeKeyValueVo> list(XQueryByTreeValueDto queryDto) {
        return null;
    }
}
